﻿/**************************************************************
 *
 * 命名空间：Sgr.DataCategories.Controllers
 * 创建时间：2024/1/1
 * 描述：数据字典查询控制器
 *
 **************************************************************/

using Microsoft.AspNetCore.Mvc;
using Sgr.AspNetCore.ActionFilters.AuditLogs;
using Sgr.AspNetCore.ActionFilters.Permissions;
using Sgr.DataCategories.Services;
using System.Collections.Concurrent;

namespace Sgr.DataCategories.Controllers
{
    /// <summary>
    /// 数据字典查询接口
    /// </summary>
    [Route("api/v1/sgr/category-lookup")]
    [ApiController]
    [Produces("application/json")]
    [Tags("CategoryLookup")]
    public class CategoryLookupController : ControllerBase
    {
        private readonly ICategoryItemsQuery _categoryItemsQuery;
        private readonly ICategoryTypeService _categoryTypeService;
        private readonly ICategoryItemsManagement _categoryItemsManagement;
        private readonly ILogger<CategoryLookupController> _logger;

        public CategoryLookupController(
            ICategoryItemsQuery categoryItemsQuery,
            ICategoryTypeService categoryTypeService,
            ICategoryItemsManagement categoryItemsManagement,
            ILogger<CategoryLookupController> logger)
        {
            _categoryItemsQuery = categoryItemsQuery ?? throw new ArgumentNullException(nameof(categoryItemsQuery));
            _categoryTypeService = categoryTypeService ?? throw new ArgumentNullException(nameof(categoryTypeService));
            _categoryItemsManagement = categoryItemsManagement ?? throw new ArgumentNullException(nameof(categoryItemsManagement));
            _logger = logger;
        }

        /// <summary>
        /// 获取数据字典类型列表
        /// </summary>
        /// <returns>字典类型列表</returns>
        /// <response code="200">获取成功</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission]
        [HttpGet("types")]
        [ProducesResponseType(typeof(NameValue[]), StatusCodes.Status200OK)]
        [AuditLogActionFilter("查询字典类型列表")]
        public async Task<ActionResult<NameValue[]>> GetCategoryTypesAsync(/*CancellationToken cancellationToken*/)
        {
            return Ok(await _categoryTypeService.GetAllAsync());
        }

        /// <summary>
        /// 按照字典分类编码获取字典项集合
        /// </summary>
        /// <param name="categoryTypeCode">字典分类标识编码</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>字典项集合</returns>
        /// <response code="200">获取成功</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission]
        [HttpGet("items/{categoryTypeCode}")]
        [ProducesResponseType(typeof(IEnumerable<NameValue>), StatusCodes.Status200OK)]
        [AuditLogActionFilter("按字典分类编码获取字典项集合")]
        public async Task<ActionResult<IEnumerable<NameValue>>> GetCategoryItemsAsync([FromRoute] string categoryTypeCode, CancellationToken cancellationToken)
        {
            var items = await _categoryItemsQuery.GetCategoryAsync(categoryTypeCode, cancellationToken);
            return Ok(items.Values);
        }

        /// <summary>
        /// 重置指定类型的数据字典缓存
        /// </summary>
        /// <param name="categoryTypeCode">字典分类标识编码</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>操作结果</returns>
        /// <response code="200">重置成功</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.ResetCategpryCache)]
        [HttpPost("reset/{categoryTypeCode}")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("重置指定类型的数据字典缓存")]
        public async Task<ActionResult<bool>> ResetCategoryCache(
            [FromRoute] string categoryTypeCode, CancellationToken cancellationToken)
        {
            if (string.IsNullOrEmpty(categoryTypeCode))
                return BadRequest("类型编码不能为空");

            // 获取所有基础类别类型
            var categoryTypes = await _categoryTypeService.GetAllAsync();
            if (!categoryTypes.Any(f => f.Value == categoryTypeCode))
                return BadRequest($"类型编码 {categoryTypeCode} 不存在");

            await _categoryItemsManagement.RefreshCategoryAsync(categoryTypeCode, cancellationToken);
            return true; ;
        }

        /// <summary>
        /// 重置所有基础类别类型的数据字典缓存(除行政区划以外)
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>操作结果</returns>
        /// <response code="200">重置成功</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(Permissions.ResetCategpryCache)]
        [HttpPost("reset-all-basics")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("重置所有基础类别类型的数据字典缓存")]
        public async Task<ActionResult<bool>> ResetAllBasicCategoriesCache(CancellationToken cancellationToken)
        {
            // 获取所有基础类别类型
            var categoryTypes = await _categoryTypeService.GetAllAsync();
            var failedList = new ConcurrentBag<string>();

            var refreshTasks = categoryTypes
                .Select(async ct =>
                {
                    try
                    {
                        await _categoryItemsManagement.RefreshCategoryAsync(ct.Value, cancellationToken);
                    }
                    catch (Exception ex)
                    {
                        failedList.Add(ct.Value);
                        _logger.LogError(ex, $"重置类型 {ct.Value} 的数据字典缓存失败");
                    }
                })
            .ToArray();

            await Task.WhenAll(refreshTasks);

            return failedList.IsEmpty;
        }
    }
}